﻿// This software is the confidential and proprietary information of NetBay.
// Such confidential information should not be disclosed.
// NetBay copyright(c) 2012

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Input;
using System.Xml.Linq;
using NetBay.Core.BusinessEntities;
using Rio.Framework.Localisation;
using Rio.Framework.Pages.AppCode.Models;
using Rio.Framework.Pages.Context;
using Telerik.Windows.Controls.DragDrop;

namespace Rio.Framework.Pages.CriteriaControls
{
    public partial class ItemTreeview
    {
        #region Attributs

        public static readonly DependencyProperty ItemsListProperty =
            DependencyProperty.Register("ItemsList", typeof (DataItemTreeViewCollection), typeof (ItemTreeview), null);

        private DataItemTreeView _currentItem;

        #endregion

        #region Properties

        /// <summary>
        ///   Gets or sets the contain trash item.
        /// </summary>
        /// <value>The contain trash item.</value>
        public bool ContainTrashItem { get; private set; }

        /// <summary>
        ///   Gets or sets the items list.
        /// </summary>
        /// <value>The items list.</value>
        public DataItemTreeViewCollection ItemsList
        {
            get { return (DataItemTreeViewCollection) GetValue(ItemsListProperty); }
            set { SetValue(ItemsListProperty, value); }
        }

        /// <summary>
        ///   Gets or sets the is search mode.
        /// </summary>
        /// <value>The is search mode.</value>
        public bool IsSearchMode { get; set; }

        /// <summary>
        ///   Gets or sets the current item.
        /// </summary>
        /// <value>The current item.</value>
        public DataItemTreeView CurrentSelectedItem
        {
            get { return _currentItem; }
            set
            {
                _currentItem = value;
                OnPropertyChanged("CurrentSelectedItem");
                RaiseTreeItemChanged(value);
            }
        }

        /// <summary>
        ///   Gets or sets the type of the current folder.
        /// </summary>
        /// <value>The type of the current folder.</value>
        public FolderType CurrentFolderType { get; set; }

        #endregion

        #region Constructors

        /// <summary>
        ///   Initializes a new instance of the <see cref = "ItemTreeview" /> class.
        /// </summary>
        public ItemTreeview()
        {
            InitializeComponent();
            IsSearchMode = false;
            ItemsList = new DataItemTreeViewCollection(null);
        }

        #endregion

        #region Public functions

        /// <summary>
        ///   Clears the items.
        /// </summary>
        public void ClearItems()
        {
            ItemsList.Clear();
        }

        /// <summary>
        ///   Clears the selection.
        /// </summary>
        public void ClearSelection()
        {
            TreeViewControlItems.SelectedItem = null;
        }

        /// <summary>
        ///   Inits the items.
        /// </summary>
        /// <param name = "folderType">Type of the folder.</param>
        public void InitItems(FolderType folderType)
        {
            CurrentFolderType = folderType;

            //get items from foldertype
            XDocument xmlItems = XDocument.Parse(CurrentFolderType.TreeNodeForItem);
            DataItemTreeViewCollection temporaryListNodeTreeView;

            //Create tree 
            if (!IsSearchMode)
            {
                temporaryListNodeTreeView = new DataItemTreeViewCollection(null,
                                                                           GetListNodeTreeViewWithoutRight(
                                                                               xmlItems.Element("Root")));
                temporaryListNodeTreeView.Insert(0, CreateDefaultItem());
            }
            else
            {
                temporaryListNodeTreeView = new DataItemTreeViewCollection(null) {CreateDefaultItem()};
                GetlistNodeTreeViewWithRight(xmlItems.Element("Root"), temporaryListNodeTreeView);
            }

            //bind items
            ItemsList = new DataItemTreeViewCollection(null, temporaryListNodeTreeView);
        }

        /// <summary>
        ///   Selects the default item.
        /// </summary>
        public void SelectDefaultItem()
        {
            CurrentSelectedItem = CreateDefaultItem();
        }

        /// <summary>
        ///   Adds the trash item.
        /// </summary>
        /// <param name = "documents">The documents.</param>
        public void AddTrashItem(IEnumerable<Document> documents = null)
        {
            var trash = CreateTrashItem();
            if (documents != null)
            {
                trash.ListDocument = new List<Document>(documents);
            }
            ItemsList.Insert(0, trash);
            ContainTrashItem = true;
        }

        /// <summary>
        ///   Gets the trash item.
        /// </summary>
        /// <returns></returns>
        public DataItemTreeView GetTrashItem()
        {
            if (ItemsList != null)
            {
                return ItemsList.SingleOrDefault(item => item.IsTrashItem);
            }

            return null;
        }

        #endregion

        #region Private functions

        private void TreeViewControlItemsItemPrepared(object sender,
                                                      Telerik.Windows.Controls.RadTreeViewItemPreparedEventArgs e)
        {
            RadDragAndDropManager.SetAllowDrop(e.PreparedItem, true);
        }

        /// <summary>
        ///   Applies the default item.
        /// </summary>
        private DataItemTreeView CreateDefaultItem()
        {
            DataItemTreeView defaultNode = new DataItemTreeView
                                               {
                                                   Text = Resx.GetLabel(ResxIndexPanel.ITEM_NOCLASSED),
                                                   Code = "000000000000",
                                                   IsTrashItem = false,
                                                   IsDefaultItem = true,
                                                   Items = null,
                                                   ListDocument = null,
                                                   CanBeConsult = true,
                                                   CanBeModify = true
                                               };
            return defaultNode;
        }

        /// <summary>
        ///   Gets the trash item.
        /// </summary>
        /// <returns></returns>
        private DataItemTreeView CreateTrashItem()
        {
            DataItemTreeView defaultNode = new DataItemTreeView
                                               {
                                                   Text = Resx.GetLabel(ResxCommon.TRASH),
                                                   Code = string.Empty,
                                                   IsTrashItem = true,
                                                   CanBeConsult = true,
                                                   CanBeModify = true,
                                               };
            return defaultNode;
        }

        /// <summary>
        ///   Gets the list node tree view.
        /// </summary>
        /// <param name = "element">The element.</param>
        /// <returns></returns>
        private IEnumerable<DataItemTreeView> GetListNodeTreeViewWithoutRight(XElement element)
        {
            return (element.Elements("TreeViewItem").Select(L_olistNodeTreeView => new DataItemTreeView
                                                                                       {
                                                                                           Text =
                                                                                               L_olistNodeTreeView.
                                                                                               Attribute("Header").Value,
                                                                                           Code =
                                                                                               L_olistNodeTreeView.
                                                                                               Attribute("Code").Value,
                                                                                           Items =
                                                                                               new DataItemTreeViewCollection
                                                                                               (null,
                                                                                                GetListNodeTreeViewWithoutRight
                                                                                                    (L_olistNodeTreeView))
                                                                                       })).ToList();
        }

        /// <summary>
        ///   Getlists the node tree view with right.
        /// </summary>
        /// <param name = "element">The element.</param>
        /// <param name = "dataItemTreeViewCollection">The data item tree view collection.</param>
        private void GetlistNodeTreeViewWithRight(XElement element,
                                                  DataItemTreeViewCollection dataItemTreeViewCollection)
        {
            User L_oUser = GlobalWebContext.CurrentUser;
            List<Group> L_GroupList = new List<Group>(L_oUser.GroupList);
            foreach (XElement Xitem in element.Elements("TreeViewItem"))
            {
                DataItemTreeView L_oDataItemTreeView = new DataItemTreeView
                                                           {
                                                               Text = Xitem.Attribute("Header").Value,
                                                               Code = Xitem.Attribute("Code").Value,
                                                               ListDocument = null
                                                           };
                if (!L_oDataItemTreeView.IsDefaultItem)
                {
                    DataItemTreeView view = L_oDataItemTreeView;
                    Item L_oSelectedItemInTreeView =
                        CurrentFolderType.LstItems.Where(x => x.Code.Equals(view.Code)).FirstOrDefault();
                    foreach (Group grp in L_GroupList)
                    {
                        // TOSEEFORLATER : Not implemented right now in RIO but normally to do : "(if (grp.IsAdministrator) return true;)"
                        List<ItemRights> L_oItemRightsList = new List<ItemRights>(grp.ItemRightsList);
                        ItemRights L_oSelectedItemRights = GetItemsRights(L_oItemRightsList, L_oSelectedItemInTreeView);
                        if (L_oSelectedItemRights != null)
                        {
                            if (L_oSelectedItemRights.CanModify)
                            {
                                L_oDataItemTreeView.CanBeModify = true;
                            }
                            if (L_oSelectedItemRights.CanConsult)
                            {
                                L_oDataItemTreeView.CanBeConsult = true;
                            }
                        }
                        if (!L_oDataItemTreeView.CanSubItemBeConsultOrModify)
                        {
                            L_oDataItemTreeView.CanSubItemBeConsultOrModify = VerifySubItemRights(L_oItemRightsList,
                                                                                                  Xitem);
                        }
                        if (((L_oDataItemTreeView.CanBeModify) && (L_oDataItemTreeView.CanBeConsult))
                            && (L_oDataItemTreeView.CanSubItemBeConsultOrModify))
                        {
                            break;
                        }
                    }
                    if ((L_oDataItemTreeView.CanBeModify)
                        || (L_oDataItemTreeView.CanBeConsult))
                    {
                        if (L_oDataItemTreeView.CanSubItemBeConsultOrModify)
                        {
                            GetlistNodeTreeViewWithRight(Xitem, L_oDataItemTreeView.Items);
                        }
                        dataItemTreeViewCollection.Add(L_oDataItemTreeView);
                    }
                    else
                    {
                        if (L_oDataItemTreeView.CanSubItemBeConsultOrModify)
                        {
                            GetlistNodeTreeViewWithRight(Xitem, L_oDataItemTreeView.Items);
                            dataItemTreeViewCollection.Add(L_oDataItemTreeView);
                        }
                    }
                }
            }
        }

        /// <summary>
        ///   Get ItemRights from a group switch an item
        /// </summary>
        /// <param name = "itemRightsList">The item rights list.</param>
        /// <param name = "item">The item.</param>
        /// <returns></returns>
        private ItemRights GetItemsRights(List<ItemRights> itemRightsList, Item item)
        {
            try
            {
                return itemRightsList.FirstOrDefault(x => x.Item.Identifier == item.Identifier);
            }
            catch (Exception)
            {
                return null;
            }
        }

        /// <summary>
        ///   Verifies the sub item rights.
        /// </summary>
        /// <param name = "itemRightsList">The item rights list.</param>
        /// <param name = "dITVCollection">The d ITV collection.</param>
        /// <returns></returns>
        private bool VerifySubItemRights(List<ItemRights> itemRightsList, XElement dITVCollection)
        {
            foreach (XElement Xitem in dITVCollection.Elements("TreeViewItem"))
            {
                DataItemTreeView L_oDataItemTreeView = new DataItemTreeView
                                                           {
                                                               Text = Xitem.Attribute("Header").Value,
                                                               Code = Xitem.Attribute("Code").Value,
                                                               ListDocument = null
                                                           };

                DataItemTreeView view = L_oDataItemTreeView;
                Item L_oSelectedItemInTreeView =
                    CurrentFolderType.LstItems.Where(x => x.Code.Equals(view.Code)).FirstOrDefault();

                ItemRights L_oSelectedItemRights = GetItemsRights(itemRightsList, L_oSelectedItemInTreeView);

                if (L_oSelectedItemRights != null)
                {
                    if ((L_oSelectedItemRights.CanModify)
                        || (L_oSelectedItemRights.CanConsult))
                    {
                        return true;
                    }
                }

                bool L_bSubItemRights = VerifySubItemRights(itemRightsList, Xitem);
                if (L_bSubItemRights)
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        ///   Double click on treenode
        /// </summary>
        /// <param name = "sender">The source of the event.</param>
        /// <param name = "e">The <see cref = "System.Windows.RoutedEventArgs" /> instance containing the event data.</param>
        private void Item_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (e.ClickCount == 2)
            {
                RaiseItemDblClicked(CurrentSelectedItem);
            }
        }

        #endregion
    }
}